package cn.lhl01.util;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class PermissionCollectUtils {


	public static final String VALUE = "value";

	/**
	 * @param resourcePatternResolver
	 * @param classpath               路径
	 * @param annotationClass         哪个注解
	 * @param <T>
	 * @return
	 * @throws Exception
	 */
	public static <T> List<Map<String, Object>> getAll(ResourcePatternResolver resourcePatternResolver, String classpath, Class<T> annotationClass) throws Exception {

		//获取 classpath下的类
		Resource[] resources = resourcePatternResolver.getResources(classpath);
		MetadataReaderFactory metaReader = new CachingMetadataReaderFactory();
		List<Map<String, Object>> rsMap = new ArrayList<>();
		for (Resource r : resources) {
			MetadataReader reader = metaReader.getMetadataReader(r);
			//解析注解
			resolveClass(reader, rsMap, annotationClass);
		}
		return rsMap;
	}

	/**
	 * 解析注解
	 *
	 * @param reader
	 * @param maps
	 * @param annotationClass
	 * @param <T>
	 * @throws Exception
	 */
	private static <T> void resolveClass(MetadataReader reader, List<Map<String, Object>> maps, Class<T> annotationClass) throws Exception {
		String tagAnnotationClassCanonicalName = annotationClass.getCanonicalName();
		//获取类注解元数据
		AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
		Set<MethodMetadata> annotatedMethods = annotationMetadata.getAnnotatedMethods(tagAnnotationClassCanonicalName);

		for (MethodMetadata annotatedMethod : annotatedMethods) {

			//获取当前方法中要扫描注解的属性
			Map<String, Object> targetAttr = annotatedMethod.getAnnotationAttributes(tagAnnotationClassCanonicalName);
			// 这里增加了读取ApiOperation注解的值，如果不需要，则不取即可，
			// 同理，也可以获取其他注解的值
//			MultiValueMap<String, Object> allAnnotationAttributes = annotatedMethod.getAllAnnotationAttributes(PostMapping.class.getCanonicalName());
//			if (null != allAnnotationAttributes && allAnnotationAttributes.size() > 0) {
//				targetAttr.put("url", allAnnotationAttributes.getFirst(VALUE));
//			}

			maps.add(targetAttr);
		}

	}

}
